;requirejs && requirejs.config({
    baseUrl: './',
    paths: {
        'jquery': 'lib/jquery-1.11.1.min',
        'socket.io' : 'socket.io/socket.io',
        'handlebars' : 'lib/handlebars-v1.3.0',
		'bootstrap' : 'dist/js/bootstrap.min'
    },
    shim : {
        'bootstrap' : {
            deps : ['jquery']
        },
        'handlebars': {
            exports: 'Handlebars'
        }
    }
});


(function(factory) {
	if(typeof define === 'function' && define.amd) {
		require(['frame/XFrame_Graph', 'ext/Gomoku', 'jquery', 'handlebars', 'socket.io', 'bootstrap'], factory);
	}else {
		factory(XFrame_Graph, Gomoku, $, Handlebars, io, window);
	}
}(function(XFrame_Graph, Gomoku, $, Handlebars, io) {
	$(function(){
        var $userName = $('#userName'), $userNameDiv = $('#userNameDiv'), $rooms = $('#rooms'), nowUser, joined = false,
            $mainGomoku = $('#mainGomoku'), roomTpl = Handlebars.compile($('#roomTpl').text()), $chatInp = $('#chatInp'),
            roomPlayersTpl = Handlebars.compile($('#roomPlayersTpl').text()), noticeTpl = Handlebars.compile($('#noticeTpl').text()),
            $sysNotice = $('#sysNotice'),$noticeContent = $('#noticeContent'), $roomMsg = $('#roomMsg'), $roomMsgScroll = $('#roomMsgScroll'), socket,
            msgTpl = Handlebars.compile('<li class="text-{{type}} text-{{pos}}"><strong>{{username}}</strong>&nbsp;&nbsp;<span>{{content}}</span></li>');

        $('#userLogin').on('shown.bs.modal', function(){
            $userName.focus();
        });

        $userName.keypress(function(e){
            if(e.keyCode === 13){
                $('#doLogin').trigger('click');
            }
        });

        $('#doLogin').click(function(){
            var un = $userName.val();
            if(!un){
                $userNameDiv.addClass('has-error');
                return;
            }

            socket = io.connect(window.location.protocol + '//' + window.location.host);

            socket.on('connect', function(){
                if(socket.connected){
                    $('#userLogin').modal('hide');
                    $('.jumbotron').fadeOut().promise().then(function(){
                        $('body').css('marginTop', '70px');
                        return $('.main-platform-content').fadeIn().promise();
                    }).then(function(){
                        socket.emit('getRooms', {});
                        socket.emit('login', {username: un});
                    });
                    Gomoku.initGomoku($('#testcanvas'), socket);

                    socket.on('rooms', function(data){
                        var rooms = data.rooms;
                        $rooms.empty();
                        $.each(rooms, function(_, roomObj){
                            if(roomObj.status === 0){
                                roomObj.panelStatus = 'panel-success';
                                roomObj.panelStatusDesc = '空房间';
                                roomObj.canPlay = (!joined);
                            }else if(roomObj.status === 1){
                                roomObj.panelStatus = 'panel-primary';
                                roomObj.panelStatusDesc = '等待对手中...';
                                roomObj.canPlay = (!joined);
                            }else if(roomObj.status === 2){
                                roomObj.panelStatus = 'panel-warning';
                                roomObj.panelStatusDesc = '对战中...';
                                roomObj.canPlay = false;
                            }
                            roomObj.joined = joined;
                            roomObj.canLeave = roomObj.roomNumber === joined;

                            $rooms.append(roomTpl(roomObj));
                        });
                    });

                    socket.on('sysNotice', function(data){
                        showNotice(data);
                    });

                    socket.on('userInfo', function(userInfo){
                        nowUser = userInfo;
                        Gomoku.putUser(userInfo);
                        $('#spUserName').text(userInfo.username);
                    });

                    socket.on('enterRoom', function(roomInfo){
                        $('.main-platform-room').fadeOut().promise().then(function(){
                            $mainGomoku.fadeIn();
                            var vsInfo = roomInfo.p1.username + ' vs ' + roomInfo.p2.username;
                            $('#playRoomName').html(roomInfo.roomName + '<small>' + vsInfo + '</small>');
                            updateRoomPlayers(roomInfo);
                            Gomoku.startGame();
                        });
                    });

                    socket.on('outRoom', function(){
                        $mainGomoku.fadeOut().promise().then(function(){
                            $('.main-platform-room').fadeIn();
                            socket.emit('getRooms', {});
                            $roomMsg.empty();
                        });
                    });

                    socket.on('playerState', function(roomInfo){
                        updateRoomPlayers(roomInfo);
                    });

                    socket.on('roomMsg', function(msgInfo){
                        addNewMessage(msgInfo.username, msgInfo.type, msgInfo.pos, msgInfo.content);
                    });
                }else{
                    alert('连接失败!!');
                }
            });
        });

        $('body').delegate('.room-play', 'click', function(){
            var $this = $(this), roomNum = $this.data('roomnum');
            socket.connected && socket.emit('joinRoom', {roomNumber : roomNum, mode: 'p'});
            joined = roomNum;
        }).delegate('.room-watch', 'click', function(){
            var $this = $(this), roomNum = $this.data('roomnum');
            socket.connected && socket.emit('joinRoom', {roomNumber : roomNum, mode: 'w'});
            joined = roomNum;
        }).delegate('.room-leave', 'click', function(){
            var $this = $(this), roomNum = $this.data('roomnum');
            socket.connected && socket.emit('leaveRoom', {roomNumber : roomNum});
            joined = 0;
        }).delegate('.game-room-leave', 'click', function(){
            var status = Gomoku.getState();
            if(status.gameStarted && status.mode){
                return showNotice({noticeType : 'warning', title : '请注意', content : '您正在游戏进行中,真的要退出么?强行退出扣5分,你怕不怕?', needYN : true, backCommand : {
                    cmd : 'forceLeaveRoom',
                    after : function(){
                        joined = 0;
                    }
                }});
            }
            socket.connected && socket.emit('leaveRoom');
            joined = 0;
        }).delegate('.notice-yes', 'click', function(){
            var cmdObj = $sysNotice.data('backCmd');
            $sysNotice.data('backCmd', false);
            if(cmdObj && cmdObj.cmd){
                $sysNotice.one('hidden.bs.modal', function(){
                    socket.connected && socket.emit(cmdObj.cmd, cmdObj.data);
                    $.isFunction(cmdObj.after) && cmdObj.after(true);
                });
            }
        }).delegate('.notice-no', 'click', function(){
            var cmdObj = $sysNotice.data('backCmd');
            $sysNotice.data('backCmd', false);
            if(cmdObj && cmdObj.noCmd){
                $sysNotice.one('hidden.bs.modal', function(){
                    socket.connected && socket.emit(cmdObj.noCmd, cmdObj.noData);
                    $.isFunction(cmdObj.after) && cmdObj.after(false);
                });
            }
        }).delegate('.gomoku-game-start', 'click', function(){
            socket.connected && socket.emit('start', {});
        }).delegate('.gomoku-game-revert', 'click', function(){
            socket.connected && socket.emit('chessBack');
        }).delegate('.gomoku-game-lose', 'click', function(){
            showNotice({noticeType : 'warning', title : '请注意', content : '您确定要认输了么?', needYN : true, backCommand : {
                cmd : 'chessLose'
            }});
        }).delegate('.gomoku-game-draw', 'click', function(){
            socket.connected && socket.emit('chessDraw');
        }).delegate('.chat-send', 'click', function(){
            var content = $chatInp.val();
            if(content){
                $chatInp.val('');
                chatSend(content);
            }
        });

        $chatInp.keypress(function(e){
            var content = $chatInp.val();
            if(e.keyCode === 13){
                if(content){
                    $chatInp.val('');
                    chatSend(content);
                }
            }
        });



        function chatSend(content){
            socket.connected && socket.emit('chatSend', {content : content});
        }

        function showNotice(noticeData){
            if(noticeData.noticeType === 'danger'){
                $sysNotice.one('hidden.bs.modal', function(){
                    window.location.reload(true);
                });
            }
            $noticeContent.empty().append(noticeTpl(noticeData));
            if(noticeData.needYN && noticeData.backCommand){
                $sysNotice.data('backCmd', noticeData.backCommand);
            }
            $sysNotice.modal();
        }

        function addNewMessage(username, type, pos, content){
            $roomMsg.append(msgTpl({username : username, type : type, pos : pos, content : content}));
            $roomMsgScroll.scrollTop($roomMsg.height());
        }

        function updateRoomPlayers(roomInfo){
            var isP1 = false, isP2 = false;
            if(nowUser.username === roomInfo.p1.username){
                isP1 = true;
            }

            if(nowUser.username === roomInfo.p2.username){
                isP2 = true;
            }

            roomInfo.panelDesc1 = isP1 ? 'primary' : 'info';
            roomInfo.panelDesc2 = isP2 ? 'primary' : 'info';

            if(roomInfo.p1st === 0){
                roomInfo.canStart1 = isP1;
                roomInfo.noStart1 = !isP1;
                roomInfo.isWait1 = false;
                roomInfo.isStarted1 = false;
                roomInfo.isPlaying1 = false;
            }else if(roomInfo.p1st === 1){
                roomInfo.canStart1 = false;
                roomInfo.noStart1 = false;
                roomInfo.isWait1 = true;
                roomInfo.isStarted1 = false;
                roomInfo.isPlaying1 = false;
            }else if (roomInfo.p1st === 2){
                roomInfo.canStart1 = false;
                roomInfo.noStart1 = false;
                roomInfo.isWait1 = false;
                roomInfo.isStarted1 = isP1;
                roomInfo.isPlaying1 = !isP1;
            }
            if(roomInfo.p2st === 0){
                roomInfo.canStart2 = isP2;
                roomInfo.noStart2 = !isP2;
                roomInfo.isWait2 = false;
                roomInfo.isStarted2 = false;
                roomInfo.isPlaying2 = false;
            }else if(roomInfo.p2st === 1){
                roomInfo.canStart2 = false;
                roomInfo.noStart2 = false;
                roomInfo.isWait2 = true;
                roomInfo.isStarted2 = false;
                roomInfo.isPlaying2 = false;
            }else if (roomInfo.p2st === 2){
                roomInfo.canStart2 = false;
                roomInfo.noStart2 = false;
                roomInfo.isWait2 = false;
                roomInfo.isStarted2 = isP2;
                roomInfo.isPlaying2 = !isP2;
            }

            $('#playersPanel').empty().append(roomPlayersTpl(roomInfo));
        }

        $('form').submit(function(e){
            e.preventDefault();
        });
	});
}));